package org.fhm.zdte.common.constant.protocol;

import org.fhm.zdte.common.exception.ProtocolException;

import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * An enumeration of common response information.
 *
 * @author 谭波
 * @since 2023/11/16
 */
public enum ResponseMessageType {
    MESSAGE_SUCCESS((byte) 0b00000001, "message success"),
    MESSAGE_ACK((byte) 0b00000010, "message ack"),
    USER_LIMIT((byte) 0b00000011, "the user limit is exceeded "),
    USER_IS_OFF((byte) 0b00000100, "the user has gone offline"),
    USER_NO_ONLINE((byte) 0b00000101, "the user to whom the connection is connected is not online"),
    CONNECT_OFFLINE((byte) 0b00000110, "the connection target has gone offline"),
    CONNECT_REFUSED((byte) 0b00000111, "the connection was denied"),
    ;

    private final Byte valueBit;

    private final String desc;

    ResponseMessageType(Byte valueBit, String desc) {
        this.valueBit = valueBit;
        this.desc = desc;
    }

    public static ResponseMessageType getResponseMessageType(Byte valueBit) {
        if (Objects.isNull(valueBit))
            throw new ProtocolException("the Byte of response message type error");
        for (ResponseMessageType type : ResponseMessageType.values()) {
            if (type.valueBit.equals(valueBit))
                return type;
        }
        throw new ProtocolException("there is no matching response message type for Byte");
    }

    public static String getResponseDescByByte(ResponseMessageType type) {
        String errorTip = "message error";
        if (Objects.isNull(type)) {
            return errorTip;
        }
        for (ResponseMessageType p : ResponseMessageType.values()) {
            if (p.equals(type)) {
                return p.getDesc();
            }
        }
        return errorTip;
    }

    public static Boolean isResponseMessageType(ResponseMessageType type) {
        if (type == null) {
            throw new ProtocolException("the Byte of response message type error");
        }
        return Arrays.asList(
                ResponseMessageType.values()
        ).contains(type);
    }

    public static Boolean isFailResponseMessageType(ResponseMessageType type) {
        if (type == null) {
            throw new ProtocolException("the Byte of response message type error");
        }
        return Stream.of(
                        ResponseMessageType.values()
                )
                .filter(t -> (
                        !t.equals(MESSAGE_SUCCESS)
                                && !t.equals(MESSAGE_ACK)
                ))
                .anyMatch(t -> t.equals(type));
    }

    public Byte getValueBit() {
        return valueBit;
    }


    public String getDesc() {
        return desc;
    }
}
